var CONFIG = require('../../../../common/config');
var CODE = require('../../../../common/code');
var async = require('async');
var moment = require('moment');
var retUtil = require('../util/retUtil');
var TgUserDocModel = require('../../../../common/mysql/mapping/TgUserDocModel');
var ItbNotificationModel = require('../../../../common/mysql/mapping/ItbNotificationModel');
var ItbNotifyUserModel = require('../../../../common/mysql/mapping/ItbNotifyUserModel');
var ItbRcmdRewardModel = require('../../../../common/mysql/mapping/ItbRcmdRewardModel');
var ItbUserModel = require('../../../../common/mysql/mapping/ItbUserModel');
var ItbMemberModel = require('../../../../common/mysql/mapping/ItbMemberModel');
var superagent = require('superagent');
var cacheManager = require('cache-manager');
var redisStore = require('cache-manager-redis');
var vcdRedisCache = cacheManager.caching({
    store: redisStore,
    host: CONFIG.VCODE_REDIS_SERVER_DOMAIN,
    port: CONFIG.VCODE_REDIS_SERVER_PORT,
    auth_pass: CONFIG.VCODE_REDIS_SERVER_PASSWORD,
    db: CONFIG.VCODE_REDIS_SERVER_DB_NUMBER,
    ttl: CONFIG.VCODE_REDIS_SERVER_TTL,
    //prefix: CONFIG.VCODE_REDIS_SERVER_PREFIX
});

var userUtil = (function () {

    function userUtil() {

    }


    //----------------------------------------------------------------
    /**
     * 获取用户文档
     * 参数: userId
     * 参数: typeL: 0 未分类(返回所有); 1 海报; 2 多页; 3 ppt; 4 印品
     * 参数: pageNum: 请求页号(0开始 )
     * 参数: pageSize: 请求页大小(空或0时获取所有)
     * 参数: callback
     * */
    userUtil.getUserDocsV6_4=function(userId,typeL,pageNum,pageSize, callback){
        (new TgUserDocModel).getUserDocsByTypeLV6_4(userId,typeL,pageNum,pageSize,callback);
    };


    /**
     * 获取用户文档个数
     * 参数: userId
     * 参数: typeL: 0 未分类(返回所有); 1 海报; 2 多页; 3 ppt; 4 印品
     * 参数: pageNum: 请求页号(0开始 )
     * 参数: pageSize: 请求页大小(空或0时获取所有)
     * 参数: callback
     * */
    userUtil.getUserDocsCntV6_4=function(userId,typeL,pageNum,pageSize, callback){
        (new TgUserDocModel).getUserDocsByTypeLCntV6_4(userId,typeL,callback);
    };
    /***
     * 获取用户作品列表_APP_6_4 添加
     * @author 毛凯
     * @date 2018-4-19
     * @param userId   用户唯一标识
     * @param typeL   [1] 一级分类数组的 json 字符串
     * @param pageNum   页码, 从0 开始
     * @param pageSize   页容量
     * @param withTotalPage   0 标记不获取总页数, 1 标记获取总页数
     * @param callback 用户作品列表数组
     */
    userUtil.getUserProductsList_app_v6_4 =  function(userId,typeL,pageNum,pageSize,withTotalPage, callback){
        // 根据大分类查找用户文档
        userUtil.getUserDocsV6_4(userId, typeL, pageNum, pageSize, function(error, result){
            if(error){
                console.log(error);
                return callback(error,null);
            }
            var retData =[];
            if(result && result.length>0) {
                for (var i = 0; i < result.length; i++) {
                    retData.push({
                        id: result[i].doc_id,
                        thumb: result[i].thumb || '',
                        title: result[i].doc_name || '',
                        typeL: result[i].top_type || 0,
                        time: (new moment(result[i].create_time)).format('YYYY-MM-DD HH:mm')
                    });
                }
            }
            var data = {list:retData, currentPage : pageNum};
            // 获取总页数
            if(withTotalPage) {
                userUtil.getUserDocsCntV6_4(userId, typeL, pageNum, pageSize, function(error1, count){
                    if(error){
                        console.log(error);
                        return callback(error,null);
                    }
                    var totalPage = Math.floor((count-1)/pageSize)+1;
                    data.totalPage = totalPage;
                    return callback(null,data);
                });
            } else {
                return callback(null,data);
            }
        });
    };


    /***
     * 获取用户作品列表_APP_6_4 添加
     * @author 毛凯
     * @date 2018-4-19
     * @param userId   用户唯一标识
     * @param productCnt   一次获取用户文档个数
     * @param timestamp   最新一条通知(数组最后一个)的 start_time, 如果没有, 则传递空字符串
     * @param states   指定用户的通知类型: 状态：10 新建(未读), 20 已获取(已读), 多种状态用逗号拼接, 如: 10,20
     * @param typeL   [1] 一级分类数组的 json 字符串
     * @param callback 用户作品列表数组
     */
    userUtil.getUserPersonalCenterInfo_app_v6_4 =  function(userId,productCnt,timestamp,states,typeL,callback){
        if(productCnt>0) {
            // 获取几个用户文档
            userUtil.getUserDocsV6_4(userId, typeL, 0, productCnt, function(error, products) {
                if (error) {
                    console.log(error);
                    return callback(error, null);
                }
                // 获取广播和系统通知
                userUtil.getBroadcastAndNotifications(userId, timestamp, states, function(error, data){
                    if(error) {
                        console.log('yjsc/v2/userUtil.js [getBroadcastAndNotifications] err: ' + error);
                        return callback(error, null);
                    }
                    // 将data中的coreStructure转换为对象
                    return callback(null, { products:products, broadcast:data.broadcast, notifications:data.notifications });
                });
            });
        } else {
            // 仅获取广播和系统通知
            userUtil.getBroadcastAndNotifications(userId, timestamp, states, function(error, data){
                if(error) {
                    console.log('yjsc/v2/userUtil.js [getBroadcastAndNotifications] err: ' + error);
                    return callback(error, null);
                }
                // 将data中的coreStructure转换为对象
                return callback(null, { products:[], broadcast:data.broadcast, notifications:data.notifications });
            });
        }
    };


    //----------------------------------------------------------------
    /**
     * 广播／通知 (默认会更新通知状态)
     * 参数: userId	用户唯一标识
     * 参数: timestamp 	查询[有效期]在此[时间戳]之后的活动广播 "2017-04-11 10:14:00" (19位年月日十分秒)
     * 参数: states  用户通知的状态(逗号链接字符串): "10,20"
     * 参数: callback,参数如下：
     *          error,错误
     *          data,对象：
     *                                   {
     *                                          "broadcast":[
     *                                              {
     *                                                  "title":"广播标题",
     *                                                  "message":"消息内容",
     *                                                  "url":"http://www.itbour.com",
     *                                                  "start_time":"2017-04-11 10:14:00"
     *                                              }
     *                                          ],
     *                                          "notifications":[
     *                                              {
     *                                                  "title":"系统通知",
     *                                                  "message":"感谢您的意见反馈",
     *                                                  "url":"http://www.itbour.com",
     *                                                  "start_time":"2017-04-11 12:30:01"
     *                                              }
     *                                          ]
     *                                  }
     * */
    userUtil.getBroadcastAndNotifications=function(userId, timestamp, states, callback){
        var entity = new ItbNotificationModel();
        entity.getBroadcast(timestamp,function(error, broadcast){
            if(error){
                return callback(error, null);
            }

            broadcast = broadcast || [];

            entity.getNotifications(userId, null/*timestamp*/, states, function(error, notifications){
                if(error){
                    return callback(error, null);
                }

                notifications = notifications || [];

                if(notifications.length>0) {
                    var updIds = '';
                    for(var i=0; i<notifications.length; i++) {
                        if(i>0) updIds+=',';
                        updIds += notifications[i].r_id;
                    }

                    (new ItbNotifyUserModel).updState(userId, updIds, 20/*已获取*/, function(updErr){
                        return callback(null , {broadcast:broadcast, notifications:notifications });
                    });

                } else {
                    return callback(null , {broadcast:broadcast, notifications:[] });
                }
            });
        });
    };



    /**
     * 获取用户推荐简略信息
     *
     * @author 王俊
     * @date 2018-05-15
     *
     * @param userId        用户唯一标识
     * @param callback      回调函数
     *          err: 获取失败
     *          data: {
     *              totalRecommend : 总推荐人数,
     *              currentReward : 当前可兑换天数
     *              totalExchangeReward: 已兑换天数
     *          }
     */
    userUtil.getUserRecommendBriefInfo_app_v6_6 = function(userId, callback) {
        (new ItbRcmdRewardModel()).summaryUserRecommendBriefInfo(userId, function (error, info) {
            if(error) return callback(error, null);
            var ret = {
                totalRecommend : Number(info.totalRecommend || 0),
                currentReward : Number(info.currentReward || 0),
                totalExchangeReward : Number(info.totalExchangeReward || 0)
            };
            return callback(error, ret);
        });
    };

    /**
     * 获取已推荐用户列表
     *
     * @author 王俊
     * @date 2018-05-15
     *
     * @param {Object} options 请求参数
     * @param {Number} options.userId       用户唯一标识
     * @param {Number} options.pageNum      页码
     * @param {Number} options.pageSize     页容量
     * @param {Number} options.withTotalPage 是否获取总页数
     * @param callback
     */
    userUtil.getRecommendUserList = function (options, callback) {

        var totalTasks = [];

        // 1.获取列表
        totalTasks.push(function (callback) {
            (new ItbRcmdRewardModel()).getRcmdUsersList(options, function (error, list) {
                var data = {};
                data.list = list || [];
                return callback(error, data);
            });
        });
        // 2. 按需获取总页数
        if(options.withTotalPage) {
            totalTasks.push(function (data, callback) {
                (new ItbRcmdRewardModel()).getRcmdUsersListCnt(options, function (error, totalCnt) {
                    data.totalPage = Math.floor((totalCnt-1)/options.pageSize)+1;
                    return callback(error, data);
                });
            });
        }
        async.waterfall(totalTasks, function (error, data) {
            return callback(error, data);
        });
    };

    /**
     * 用户兑换推荐奖励
     *
     * @author 王俊
     * @date 2018-05-15
     *
     * @param {Object} options 参数
     * @param {Number} options.userId 用户唯一标识
     * @param {Function} callback 回调函数
     */
    userUtil.exchangeRecommendAward = function (options, callback) {

        var totalTasks = [];

        // 1. 获取可兑换天数
        totalTasks.push(function (callback) {
            (new ItbRcmdRewardModel()).summaryUserRecommendBriefInfo(options.userId, function (error, briefInfo) {
                if(error) {
                    return callback(error, null);
                }
                var data = {};
                // 暂时兑换所有剩余天数
                data.exchangeDays = briefInfo.currentReward || 0;
                if(!data.exchangeDays || data.exchangeDays <=0) {
                    return callback('暂无可兑换天数', null);
                }
                return callback(error, data);
            });
        });
        // 2. 扣除奖励
        totalTasks.push(function (data, callback) {
            var entity = new ItbRcmdRewardModel();
            /*
             * @param {Number} options.userId       更新人
             * @param {Number} options.rcmdTo       被推荐人 id
             * @param {Number} options.rcmdBy       推荐人 id
             * @param {Number} options.rewardType   奖励类型, 默认为0
             * @param {Number} options.rewardAmt    奖励数量
             * @param {Number} options.exchangeAmt  兑换数量
             * @param {Number} options.autoExchange 是否自动兑换
             * @param {String} options.desc 请求参数
            * */
            var opt = {
                userId : options.userId,
                rcmdTo : 0,
                rcmdBy : 0,
                rewardType : 0,
                rewardAmt : 0,
                exchangeAmt : data.exchangeDays,
                autoExchange : 0,
                desc : '推荐人兑换记录'
            };
            entity.updRcmdRewardInfo(opt, function (error, retCode) {
                return callback(error, data);
            });
        });

        // 3. 增加 vip 时长
        totalTasks.push(function (data, callback) {
            var opt = {
                userId : options.userId,
                type : 1,
                day : data.exchangeDays
            };
            userUtil.refreshUserVipInfo(opt, function (error, memberId) {
                return callback(error, data);
            });
        });

        // 顺序执行
        async.waterfall(totalTasks, function (error, data) {
            if(error) return callback(error, null);
            return callback(error, data);
        });

    };

    /**
     * 接受邀请注册并获得vip 时长奖励
     *
     * @author 王俊
     * @date 2018-05-15
     *
     * @param {Object} options   请求参数
     * @param {Number} options.inviteUserId     邀请人唯一标识
     * @param {Number} options.zone             用户区号
     * @param {Number} options.mobile           手机号
     * @param {Number} options.verCode          验证码
     * @param {String} options.uuid             用户设备唯一标识
     * @param {Function} callback 回调函数
     */
    userUtil.beInvitedRegister = function (options, callback) {

        var totalTasks = [];
        // 1. 参数检查, 构造对象
        totalTasks.push(function (callback) {
            if(!options.inviteUserId || options.inviteUserId <=0) {
                return callback('参数错误', null);
            }
            if(!options.mobile || !(/^1\d{10}$/).test(options.mobile + '')) {
                return callback('手机号错误', null);
            }
            var data = {};
            // 推荐人奖励三天
            data.referrerReward = 3;
            // 被推荐人奖励三天
            data.recommendedReward = 3;
            // 奖励类型, 默认
            data.rewardType = 0;
            return callback(null, data);
        });
        // 2. 验证验证码
        totalTasks.push(function (data, callback) {
            userUtil.checkMobileVerCode(options.zone, options.mobile, options.verCode, function (error) {
                return callback(error, data);
            });
        });
        // 3. 检查用户是否已注册
        totalTasks.push(function (data, callback) {
            userUtil.checkMobileIsRegister(options.zone, options.mobile, function (error, userInfo) {
                if(error || userInfo) {
                    return callback(error || '该手机号已注册', data);
                }
                return callback(null, data);
            });
        });
        // 4. 注册用户
        totalTasks.push(function (data, callback) {
            userUtil.registerUserByMobile(options.zone, options.mobile, options.uuid, function (error, userId) {
                if(error) return callback(error, data);
                data.newUserId = userId;
                return callback(error, data);
            });
        });
        // 5. 插入推荐人推荐成功记录
        totalTasks.push(function (data, callback) {
            var entity = new ItbRcmdRewardModel();
            /*
             * @param {Number} options.userId       更新人
             * @param {Number} options.rcmdTo       被推荐人 id
             * @param {Number} options.rcmdBy       推荐人 id
             * @param {Number} options.rewardType   奖励类型, 默认为0
             * @param {Number} options.rewardAmt    奖励数量
             * @param {Number} options.exchangeAmt  兑换数量
             * @param {Number} options.autoExchange 是否自动兑换
             * @param {String} options.desc 请求参数
            * */
            var opt = {
                userId : options.inviteUserId,
                rcmdTo : data.newUserId,
                rcmdBy : options.inviteUserId,
                rewardType : data.rewardType,
                rewardAmt : data.referrerReward,
                exchangeAmt : 0,
                autoExchange : 0,
                desc : '推荐人推荐记录'
            };
            entity.updRcmdRewardInfo(opt, function (error, retCode) {
                return callback(error, data);
            });
        });
        // 6. 插入被推荐人获取奖励和兑换奖励记录
        totalTasks.push(function (data, callback) {
            var entity = new ItbRcmdRewardModel();
            var opt = {
                userId : data.newUserId,
                rcmdTo : data.newUserId,
                rcmdBy : options.inviteUserId,
                rewardType : data.rewardType,
                rewardAmt : data.recommendedReward,
                exchangeAmt : 0,
                autoExchange : 1,
                desc : '被推荐人响应推荐记录'
            };
            entity.updRcmdRewardInfo(opt, function (error, retCode) {
                return callback(error, data);
            });
        });
        // 7. 被推荐人立即增删 vip
        totalTasks.push(function (data, callback) {
            var opt = {
                userId : data.newUserId,
                type : 1,   // 标记增加 vip
                day : 3     // 标记需要增加 vip 的天数
            };
            data.rewardDays = opt.day;
            userUtil.refreshUserVipInfo(opt, function (error, memberId) {
                return callback(error, data);
            });
        });
        // 顺序执行
        async.waterfall(totalTasks, function (error, data) {
            if(error) return callback(error, null);

            var ret = {
                rewardDays : data.recommendedReward
            };
            return callback(error, ret);
        });
    };


    /**
     * 检查验证码
     *
     * @author 王俊
     * @date 2018-05-15
     *
     * @param {Number} zone      区号
     * @param {Number} mobile    手机号
     * @param {Number} verCode   验证码
     * @param {Function} callback  回调函数
     *                      err:   验证失败原因
     */
    userUtil.checkMobileVerCode = function (zone, mobile, verCode, callback) {

        var redisKey = zone + '-' + mobile;
        vcdRedisCache.get(redisKey, function (error, value) {
            if(error) {
                console.log('userUtil.checkMobileVerCode getValue err ' + error);
                return callback(error, false);
            }

            var record = retUtil.safe_parser_JSON_string(value);
            if(!record) return callback('尚未发送验证码', null);

            var recordTime = record.vcode_create_time;
            var curTime = Math.floor(Date.now() / 1000);
            if (curTime - recordTime > 5*60) {
                return callback('验证码已失效', null);
            }
            if(Number(record.vcode) !== Number(verCode)) {
                return callback('验证码错误', null);
            }

            return callback(null);
        });
    };

    /**
     * 通过手机号注册用户
     *
     * @author 王俊
     * @date 2018-05-15
     *
     * @param zone      区号
     * @param mobile    手机号
     * @param uuid      设备唯一标识
     * @param callback  回调
     *          err:    注册失败
     *          userId: 用户唯一标识
     */
    userUtil.registerUserByMobile = function (zone, mobile, uuid,callback) {

        var DEF_PW = 'ED035DE6D7392A03642D246BC95D06A2';// DefaultFromWechatBindMobile
        var userEntity = new ItbUserModel({
            user_type : 1,
            user_name : mobile,
            nickname : mobile,
            mobile : mobile,
            uuid : uuid,
            password : DEF_PW
        });
        userEntity.saveToDB(function (error, userId) {
            return callback(error, userId);
        });
    };

    /**
     * 检测手机号是否已注册
     *
     * @author 王俊
     * @date 2018-05-15
     * @param zone    区号
     * @param mobile  手机号
     * @param callback 回调函数
     *          error: 查询失败
     *          userInfo: 不为 null 标记用户已存在
     */
    userUtil.checkMobileIsRegister = function (zone, mobile, callback) {
        var entity = new ItbUserModel({
            mobile : mobile,
            user_type : 1,
            del_flg : 0
        });
        entity.findFromDB(function (error, users) {
            if(error || !users || users.length <=0) {
                return callback(error, null);
            }
            return callback(error, users[0]);
        });
    };

    /**
     * 刷新用户 vip 信息
     *
     * @author 王俊
     * @date 2018-05-15
     *
     * @param options   接口参数
     * @param {Number} options.userId 用户唯一标识
     * @param {Number} options.type   1 标记增加 vip,  0 标记减少 vip
     * @param {Number} options.year   标记增加多少年 vip
     * @param {Number} options.quarter 标记增加季度
     * @param {Number} options.month  标记增加多少月 vip
     * @param {Number} options.week    标记增加轴
     * @param {Number} options.day    标记增加多少天 vip
     * @param {Function} callback 回调函数
     *                      err:  操作失败
     *
     * 注意: 暂时只支持 同时更新一种单位, 若有 year 则只更新 year, 其余忽略
     */
    userUtil.refreshUserVipInfo = function (options, callback) {

        var totalTasks = [];
        // 1. 异常提示
        totalTasks.push(function (callback) {
            if (options.type !== 1) {
                return callback('暂不支持减少 vip 操作', null);
            }

            // var UNIT_MAP = {
            //     '年':1, '年度':1,
            //     '季':2, '季度':2,
            //     '月':3, '月度':3,
            //     '周':4, '星期':4,
            //     '天':5, '日':5
            // };
            var data = {};
            data.qty = options.year || options.quarter || options.month || options.week || options.day || 0;
            if(data.qty <=0) return callback('参数错误', null);
            if(data.qty === options.day)        data.unit = 5;
            if(data.qty === options.week)       data.unit = 4;
            if(data.qty === options.month)      data.unit = 3;
            if(data.qty === options.quarter)    data.unit = 2;
            if(data.qty === options.year)       data.unit = 1;
            return callback(null, data);
        });
        // 2. 查询 vip 信息
        totalTasks.push(function (data, callback) {
            var vipEntity = new ItbMemberModel();
            vipEntity.findVipMember(options.userId, function (error, vipInfo) {
                // 记录 vip 信息
                data.vipInfo = vipInfo;
                if(data.vipInfo) {
                    // 记录开始时间
                    data.stTime = vipInfo.str_expiry_time
                }
                return callback(error, data);
            });
        });
        // 3. 按需获取有效期信息
        totalTasks.push(function (data, callback) {
            if(data.stTime && data.stTime.length >0) {
                return callback(null, data);
            }
            var entity = new ItbMemberModel();
            entity.getTimeFromDB(function (error, dbTime) {
                data.dbTime = dbTime;
                if(data.dbTime) {
                    data.stTime = dbTime.str_sysdate;
                }
                return callback(error, data);
            });
        });
        // 4. 不存在会员信息则创建, 并设置有效期
        totalTasks.push(function (data, callback) {
            if(data.vipInfo) {
                return callback(null, data);
            }
            var entity = new ItbMemberModel();
            var opt = {
                userId : options.userId,
                stTime : data.stTime,
                unit : data.unit,
                qty : data.qty
            };
            entity.createVipMemberPro(opt, function (error, memberId) {
                data.memberId = memberId;
                return callback(error, data);
            });
        });
        // 5. 存在会员信息则增加有效期
        totalTasks.push(function (data, callback) {
            if(!data.vipInfo) {
                return callback(null, data);
            }
            var entity = new ItbMemberModel();
            // 决定是否累计
            var reset = Number(data.vipInfo.validFlg) === 1 ? 0 : 1;
            var opt = {
                userId : options.userId,
                stTime : data.stTime,
                unit : data.unit,
                qty : data.qty,
                reset : reset
            };
            entity.updVipMemberExpTimePro(opt, function (error) {
                return callback(error, data);
            });
        });


        async.waterfall(totalTasks, function (error, data) {
            if(error) {
                return callback(error, null);
            }
            return callback(error, {});
        });
    };

    /***
     * 发送验证码_APP_6_6 添加
     * @author 李强
     * @date 2018-05-15
     * 方式: GET
     * 参数: mobile: 手机号
     * 参数: zone: 区号
     * 返回: {}
     */
    userUtil.sendVerCode_app_v6_6 = function(zone,mobile,callback){
        var redisKey = zone + '-' + mobile;
        // 检测redis
        vcdRedisCache.get(redisKey, function (error, result) {
            // 避免mobile被连续发送验证码
            var quickly = false;
            var recd = JSON.parse(result || '{}');
            if (recd && recd.vcode_mobile && recd.vcode_create_time) {
                var cur_time = Math.floor(Date.now() / 1000);//process.uptime();
                if (cur_time - Number(recd.vcode_create_time || '0') < 60) {
                    quickly = true;
                }
            }
            if (quickly) {
                return callback("您发送验证码太过频繁",null);
            }
            // 发送验证码
            var url = 'http://'+CONFIG.SMS_SERVER_DOMAIN+':'+CONFIG.SMS_SERVER_PORT
                +'/itbweb/itbCom/sendVerCode.action?mobile='+mobile;
            //测试用地址
            superagent.get(url)
                .end(function (err, res2) {
                    if (err) {
                        return callback("发送失败,请再试试!",null);
                    }
                    var retJson = JSON.parse(res2.text);
                    // 缓存验证码信息
                    if (retJson) {
                        if(retJson.success == 1) {
                            var newRecd = {
                                vcode_mobile: mobile || '',
                                vcode: retJson.data.code || '',
                                vcode_create_time: Math.floor(Date.now() / 1000),//process.uptime()
                            };
                            var redisValue = JSON.stringify(newRecd);
                            vcdRedisCache.set(redisKey, redisValue, {ttl: 60 * 5});// 设置失效时间5分钟
                            return callback(null, {});
                        }else if(retJson.success == 0 && (retJson.msg == "Aliyun ClientException: Frequency limit reaches." || retJson.msg == "isv.BUSINESS_LIMIT_CONTROL")){
                            return callback("获取验证码超过最大限制，明天再来吧", {});
                        }else{
                            return callback("发送失败,请再试试!", {});
                        }
                    } else {
                        return callback("发送失败,请再试试!", {});
                    }
                });
        });
    };



    return userUtil;
})();
module.exports = userUtil;